#include "ILI9342.h"
#include "sys_delay.h"
#include "sys_io.h"
#include "sys_gpio.h"
#include "sys_uart.h"
#include "sys_lcd.h"

#define LCD_RESET_0 GPIO_RESET(GPIOD, GPIO_Pin_0)
#define LCD_RESET_1 GPIO_SET(GPIOD, GPIO_Pin_0)
#define LCD_CS_0    GPIO_RESET(GPIOD, GPIO_Pin_21)
#define LCD_CS_1    GPIO_SET(GPIOD, GPIO_Pin_21)
#define LCD_WR_0    GPIO_RESET(GPIOD, GPIO_Pin_18)
#define LCD_WR_1    GPIO_SET(GPIOD, GPIO_Pin_18)
#define LCD_RD_0    GPIO_RESET(GPIOD, GPIO_Pin_20)
#define LCD_RD_1    GPIO_SET(GPIOD, GPIO_Pin_20)
#define LCD_RS_0    GPIO_RESET(GPIOD, GPIO_Pin_19)
#define LCD_RS_1    GPIO_SET(GPIOD, GPIO_Pin_19)
#define Delayms     delay_ms

//===================================================
// LCD 数据输出
void LCD_dat_out(void)
{
	int i = 0;
	for (i = 1; i < 9; i++)
		GPIO_Congif(GPIOD, GPIO_Pin_0 + i, GPIO_Mode_OUT, GPIO_PuPd_NOPULL);
}
//===================================================
// LCD 数据输入
void LCD_dat_in(void)
{
	int i = 0;
	for (i = 1; i < 9; i++)
		GPIO_Congif(GPIOD, GPIO_Pin_0 + i, GPIO_Mode_IN, GPIO_PuPd_NOPULL);
}

//===================================================
// 写数据
void LCD_Write_dat(unsigned char dat)
{
	int i = 0;
	for (i = 1; i < 9; i++)
	{
		if (dat & 0x1)
			GPIO_SET(GPIOD, GPIO_Pin_0 + i);
		else
			GPIO_RESET(GPIOD, GPIO_Pin_0 + i);
		dat = dat >> 1;
	}
}
//===================================================
// 读数据
unsigned char LCD_Read_dat(void)
{
	int i = 0;
	u8 dat = 0;
	LCD_dat_in();
	LCD_RS_1;
	LCD_RD_0;
	for (i = 1; i < 9; i++)
	{
		dat = dat >> 1;
		if (GPIO_READ(GPIOD, GPIO_Pin_0 + i) == 1)
			dat |= 0x80;
	}
	LCD_RD_1;
	LCD_dat_out();
	return dat;
}
//===================================================
// 写命令
void WriteCom(unsigned char cmd)
{
	LCD_RD_1;			// RDD = 1;
	LCD_RS_0;			// RS	= 0;
	LCD_Write_dat(cmd); // P1 = cmd;
	LCD_WR_0;			// WRR = 0;
	LCD_WR_1;			// WRR = 1;
}
//===================================================
// 读命令
unsigned char ReadCom(unsigned char cmd)
{
	unsigned char dat = 0;
	WriteCom(cmd);
	dat = LCD_Read_dat();
	return dat;
}

/* 读取ID */
u16 ILI9342_Read_ID(void)
{
	u16 temp = 0;
	WriteCom(0xd3);
	LCD_Read_dat();
	LCD_Read_dat();
	temp |= LCD_Read_dat();
	temp <<= 8;
	temp |= LCD_Read_dat();
	return temp;
}

void WriteData(unsigned char dat)
{
	LCD_RD_1;			// RDD = 1;
	LCD_RS_1;			// RS	= 1;
	LCD_Write_dat(dat); // P1 = dat;
	LCD_WR_0;			// WRR = 0;
	LCD_WR_1;			// WRR = 1;
}

void ili9342_io_init(void)
{
	// GPIO_Congif(GPIOD,GPIO_Pin_10,GPIO_Mode_OUT,GPIO_PuPd_NOPULL);//LCD_BLED
	lcd_bled_ctrl(0);
	GPIO_Congif(GPIOD, GPIO_Pin_0, GPIO_Mode_OUT, GPIO_PuPd_NOPULL);  // LCD_RESET
	GPIO_Congif(GPIOD, GPIO_Pin_18, GPIO_Mode_OUT, GPIO_PuPd_NOPULL); // LCD_WR
	GPIO_Congif(GPIOD, GPIO_Pin_20, GPIO_Mode_OUT, GPIO_PuPd_NOPULL); // LCD_RD
	GPIO_Congif(GPIOD, GPIO_Pin_21, GPIO_Mode_OUT, GPIO_PuPd_NOPULL); // LCD_CS
	GPIO_Congif(GPIOD, GPIO_Pin_19, GPIO_Mode_OUT, GPIO_PuPd_NOPULL); // LCD_RS
	LCD_dat_out();
}

void lcd_bled_ctrl(int en)
{
	//	  if(en)GPIO_SET(GPIOD,GPIO_Pin_10);
	//		else  GPIO_RESET(GPIOD,GPIO_Pin_10);
}

void ili9342_init(void)
{
	ili9342_io_init();

	//************LCD复位
	LCD_CS_1;
	LCD_RESET_1;
	delay_ms(50);
	LCD_RESET_0;
	delay_ms(120);
	LCD_RESET_1;
	delay_ms(150);
	LCD_CS_0;
	//************

	sysprintf("LCD ID=%04x\r\n", ILI9342_Read_ID());

	WriteCom(0xC8); // Set EXTC
	WriteData(0xFF);
	WriteData(0x93);
	WriteData(0x42);

	WriteCom(0x36);	 // Memory Access Control
	WriteData(0xC8); // MY,MX,MV,ML,BGR,MH
	WriteCom(0x3A);	 // Pixel Format Set
	WriteData(0x55); // DPI [2:0],DBI [2:0]

	WriteCom(0xC0);	 // Power Control 1
	WriteData(0x15); // VRH[5:0]
	WriteData(0x15); // VC[3:0]

	WriteCom(0xC1);	 // Power Control 2
	WriteData(0x01); // SAP[2:0],BT[3:0]

	WriteCom(0xC5); // VCOM 电压
	// WriteData(0xFC);//0xFA     F5
	WriteData(0xC0); // 0xFA     C2

	WriteCom(0xB1);
	WriteData(0x00);
	WriteData(0x1B);
	WriteCom(0xB4);
	WriteData(0x02);

	WriteCom(0xE0);
	WriteData(0x0F); // P01-VP63
	WriteData(0x13); // P02-VP62
	WriteData(0x17); // P03-VP61
	WriteData(0x04); // P04-VP59
	WriteData(0x13); // P05-VP57
	WriteData(0x07); // P06-VP50
	WriteData(0x40); // P07-VP43
	WriteData(0x39); // P08-VP27,36
	WriteData(0x4F); // P09-VP20
	WriteData(0x06); // P10-VP13
	WriteData(0x0D); // P11-VP6
	WriteData(0x0A); // P12-VP4
	WriteData(0x1F); // P13-VP2
	WriteData(0x22); // P14-VP1
	WriteData(0x00); // P15-VP0

	WriteCom(0xE1);
	WriteData(0x00); // P01
	WriteData(0x21); // P02
	WriteData(0x24); // P03
	WriteData(0x03); // P04
	WriteData(0x0F); // P05
	WriteData(0x05); // P06
	WriteData(0x38); // P07
	WriteData(0x32); // P08
	WriteData(0x49); // P09
	WriteData(0x00); // P10
	WriteData(0x09); // P11
	WriteData(0x08); // P12
	WriteData(0x32); // P13
	WriteData(0x35); // P14
	WriteData(0x0F); // P15

	WriteCom(0x11); // Exit Sleep
	Delayms(120);
	WriteCom(0x29); // Display On

	WriteCom(0x2c);

#if 0
  lcd_clear(RED);
	lcd_bled_ctrl(1);
#endif
}
//===================================================
// 设置显示范围
void LCD_SetFange(unsigned short start_x, unsigned short end_x, unsigned short start_y, unsigned short end_y)
{
	WriteCom(0x2A);			 // start x
	WriteData(start_x >> 8); // end x
	WriteData(start_x);
	WriteData(end_x >> 8);
	WriteData(end_x);

	WriteCom(0x2B); // start y
	WriteData(start_y >> 8);
	WriteData(start_y & 0xff);
	WriteData(end_y >> 8); // end y
	WriteData(end_y & 0xff);
}
//===================================================
// 清屏
void lcd_clear(unsigned short color)
{
	unsigned int i, j;
	for (i = 0; i < 240; i++)
	{
		for (j = 0; j < 320; j++)
		{
			WriteData((color >> 8) & 0xff);
			WriteData(color & 0xff);
		}
	}
}
//===================================================
// 色块
void lcd_draw_rectangle(int x, int y, int w, int h, unsigned short color)
{
	unsigned int i;
	LCD_SetFange(x, x + w - 1, y, y + h - 1);
	WriteCom(0x2C);
	for (i = 0; i < (w * h); i++)
	{
		WriteData((color >> 8) & 0xff);
		WriteData(color & 0xff);
	}
}
//===================================================
// 写点
void lcd_write_dot(int x, int y, unsigned short color)
{
	LCD_SetFange(x, x, y, y);
	WriteCom(0x2C);
	WriteData((color >> 8) & 0xff);
	WriteData(color & 0xff);
}
//===================================================
// 读点
unsigned short lcd_read_dot(int x, int y)
{
	unsigned char red = 0, green = 0, blue = 0;
	LCD_SetFange(x, x, y, y);
	WriteCom(0x2e);
	LCD_Read_dat();
	red = LCD_Read_dat();
	green = LCD_Read_dat();
	blue = LCD_Read_dat();
	return (unsigned short)RGB888TO565(red, green, blue);
}
//===================================================
// 显示全屏图片
void lcd_picture(unsigned char *buf)
{
	int i, len = LCD_HS * LCD_WS;
	LCD_SetFange(0, 320 - 1, 0, 240 - 1);
	WriteCom(0x2C);
	for (i = 0; i < len; i++)
	{
		WriteData(buf[i * 2 + 1]);
		WriteData(buf[i * 2 + 0]);
	}
}
